/*
 * MicroEmulator 
 * Copyright (C) 2001 Bartek Teodorczyk <barteo@barteo.net>
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * 
 * Contributor(s): 
 *   3GLab
 *   Robert Helmer
 */
 /**
  * BlueWhaleSystems fix: Ramesh Nair - 15 May 2008
  * Refactored common listener code into {@link TextFieldInputMethodListenerBase}.
  */
package javax.microedition.lcdui;

import org.microemu.device.InputMethodEvent;
import org.microemu.device.InputMethodListener;

// Referenced classes of package javax.microedition.lcdui:
//            Form, StringComponent, Screen

abstract class TextFieldInputMethodListenerBase
    implements InputMethodListener
{

    TextFieldInputMethodListenerBase()
    {
    }

    protected abstract StringComponent sc();

    protected abstract void doRepaint();

    protected abstract Screen owner();

    public void caretPositionChanged(InputMethodEvent event)
    {
        sc().stopHighlightingText();
        updateCaretPosition(event.getCaret());
    }

    public void inputMethodTextChanged(InputMethodEvent event)
    {
        sc().stopHighlightingText();
        setCaretVisible(true);
        setString(event.getText(), event.getCaret(), true);
        doRepaint();
        fireItemStateListener();
    }

    public abstract int getCaretPosition();

    protected abstract int getOldCaretPosition();

    protected abstract void setCaretPosition(int i);

    protected abstract void setCaretVisible(boolean flag);

    protected abstract void setString(String s, int i, boolean flag);

    /** 
     * @see InputMethodListener.getText()
     */
    public String getText()
    {
        return sc().getText();
    }

    public String getHighlightedText()
    {
        return sc().getHighlightedText();
    }

    public void deleteHighlightedText()
    {
        String txt = getHighlightedText();
        if(null != txt)
        {
            int newCaretPosition = sc().getHighlightedTextStartCaret();
            sc().deleteHighlightedText();
            updateCaretPosition(newCaretPosition);
            doRepaint();
            fireItemStateListener();
        }
    }

    public void highlightAllText()
    {
        updateCaretPosition(0);
        doUpdateHighlightedTextMarker(false);
        updateCaretPosition(getText().length());
        doUpdateHighlightedTextMarker(true);
    }

    private void fireItemStateListener()
    {
        Screen owner = owner();
        if(owner instanceof Form)
            ((Form)owner).fireItemStateListener();
    }

    public abstract int getConstraints();

    public abstract boolean dontAllowNewLineChar();

    public void moveCaretToBeginningOfLine(boolean shiftKeyIsDown)
    {
        int newCaretPos = sc().getCaretPositionBeginningOfCurrentRow(getCaretPosition());
        updateCaretPosition(newCaretPos);
        doUpdateHighlightedTextMarker(shiftKeyIsDown);
        doRepaint();
    }

    public void moveCaretToEndOfLine(boolean shiftKeyIsDown)
    {
        int newCaretPos = sc().getCaretPositionEndOfCurrentRow(getCaretPosition());
        updateCaretPosition(newCaretPos);
        doUpdateHighlightedTextMarker(shiftKeyIsDown);
        doRepaint();
    }

    public boolean moveCaretDown(boolean shiftKeyIsDown)
    {
        int newCaretPos = sc().getCaretPositionOneRowDown(getCaretPosition());
        if(0 <= newCaretPos)
        {
            updateCaretPosition(newCaretPos);
            doUpdateHighlightedTextMarker(shiftKeyIsDown);
            doRepaint();
            return true;
        } else
        {
            return false;
        }
    }

    public boolean moveCaretUp(boolean shiftKeyIsDown)
    {
        int newCaretPos = sc().getCaretPositionOneRowUp(getCaretPosition());
        if(0 <= newCaretPos)
        {
            updateCaretPosition(newCaretPos);
            doUpdateHighlightedTextMarker(shiftKeyIsDown);
            doRepaint();
            return true;
        } else
        {
            return false;
        }
    }

    public void moveCaretLeft(boolean shiftKeyIsDown)
    {
        updateCaretPosition(sc().getCaretPositionOneColumnLeft(getCaretPosition()));
        doUpdateHighlightedTextMarker(shiftKeyIsDown);
        doRepaint();
    }

    public void moveCaretRight(boolean shiftKeyIsDown)
    {
        updateCaretPosition(sc().getCaretPositionOneColumnRight(getCaretPosition()));
        doUpdateHighlightedTextMarker(shiftKeyIsDown);
        doRepaint();
    }

    protected abstract void doUpdateHighlightedTextMarker(boolean flag);

    public void shiftKeyIsUp()
    {
    }

    private void updateCaretPosition(int newPosition)
    {
        setCaretPosition(newPosition);
        setCaretVisible(true);
        doRepaint();
    }
}